<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>分片上传测试</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 50px auto;
            padding: 20px;
        }
        .progress-bar {
            width: 100%;
            background: #eee;
            height: 20px;
            border-radius: 10px;
            overflow: hidden;
            margin: 10px 0;
        }
        .progress {
            height: 100%;
            background: #4caf50;
            width: 0%;
            transition: width 0.3s;
        }
        button {
            padding: 10px 15px;
            margin: 5px;
            font-size: 14px;
        }
        .status {
            color: #d32f2f;
            margin: 10px 0;
        }
    </style>
</head>
<body>
<h2>分片上传测试</h2>

<input type="file" id="fileInput" />
<button onclick="startUpload()">开始上传</button>
<button onclick="cancelUpload()">取消上传</button>

<div>上传进度：</div>
<div class="progress-bar"><div class="progress" id="progressBar"></div></div>

<div id="status" class="status"></div>

<script>
    let fileId = null;
    let chunkSize = 1024 * 1024; // 每片 1MB
    let uploading = false;

    function setStatus(msg) {
        document.getElementById("status").textContent = msg;
        console.log("[上传状态]", msg);
    }

    async function request(url, data, method = "POST") {
        const formData = new FormData();
        for (let key in data) {
            formData.append(key, data[key]);
        }
        const res = await fetch(url, {
            method,
            body: formData,
        });
        const json = await res.json();
        if (!res.ok) throw new Error(json.error || '请求失败');
        return json;
    }

    async function startUpload() {
        const fileInput = document.getElementById("fileInput");
        const file = fileInput.files[0];
        if (!file) return setStatus("请先选择文件");

        if (uploading) return setStatus("正在上传中...");
        uploading = true;

        try {
            setStatus("初始化上传...");

            // 1. 初始化上传
            const initRes = await request("/fileController/init", {
                filename: file.name,
                fileSize: file.size,
                totalChunks: Math.ceil(file.size / chunkSize),
            });
            fileId = initRes.fileId;
            setStatus(`已初始化，fileId: ${fileId}`);

            const totalChunks = Math.ceil(file.size / chunkSize);
            let uploadedChunks = 0;

            // 2. 上传所有分片（并发控制，避免太多请求）
            const uploadPromises = [];
            for (let i = 0; i < totalChunks; i++) {
                const start = i * chunkSize;
                const end = Math.min(start + chunkSize, file.size);
                const chunk = file.slice(start, end);

                // 使用闭包保存 i
                uploadPromises.push(
                    (async () => {
                        const formData = new FormData();
                        formData.append("fileId", fileId);
                        formData.append("chunkNumber", i + 1); // 从 1 开始
                        formData.append("chunk", chunk);

                        try {
                            await fetch("/fileController/chunk", {
                                method: "POST",
                                body: formData,
                            });
                            uploadedChunks++;
                            const progress = Math.round((uploadedChunks / totalChunks) * 100);
                            document.getElementById("progressBar").style.width = progress + "%";
                            setStatus(`上传中... ${uploadedChunks}/${totalChunks}`);
                        } catch (err) {
                            setStatus(`分片 ${i + 1} 上传失败: ${err.message}`);
                            throw err;
                        }
                    })()
                );
            }

            // 等待所有分片上传完成
            await Promise.all(uploadPromises);

            // 3. 完成上传（合并）
            setStatus("正在合并文件...");
            const completeRes = await request("/fileController/complete", { fileId });
            setStatus(`✅ 上传成功！文件名: ${completeRes.objectName}`);
            document.getElementById("progressBar").style.width = "100%";

        } catch (err) {
            setStatus("❌ 上传失败: " + err.message);
            console.error(err);
        } finally {
            uploading = false;
        }
    }

    async function cancelUpload() {
        if (!fileId) return setStatus("无上传任务");
        if (!confirm("确定要取消上传吗？")) return;

        try {
            await fetch("/fileController/abort", {
                method: "POST",
                body: new FormData().append("fileId", fileId),
            });
            setStatus("已取消上传");
        } catch (err) {
            setStatus("取消失败: " + err.message);
        }
    }
</script>
</body>
</html>